package org.az.netty_study.p05_netty组件之EventLoop;

import io.netty.channel.EventLoop;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * EventLoop:事件循环
 *  EventLoop本质是一个单线程执行器(一个线程和一个selector的组合)，run方法可以处理channel上源源不断的io事件
 *  1.它继承自netty自己的OrderedEventExecutor(1.判断一个线程是否属于此EventLoop;2.判断自己所属的EventLoopGroup)
 *  2.也继承自juc的ScheduleExecutorService，所以可以当成ScheduleExecutorService使用
 *  EventLoopGroup -> OrderedEventExecutor -> EventExecutor -> EventExecutorGroup -> ScheduledExecutorService
 * EventLoopGroup:事件循环组
 *  EventLoopGroup包含了多个EventLoop
 *  channel会调用EventLoopGroup的register方法来绑定其中的一个EventLoop，后续该EventLoop就负责该channel上的所有io事件
 *
 */
@Slf4j
public class _1_EventLoop初体验 {
    public static void main(String[] args) {
        /**
         * 1.创建事件循环组(NioEventLoopGroup既可以处理io事件，也可以向其提交普通任务和定时任务)
         *   DefaultEventLoopGroup是另一个EventLoopGroup实现类，只能处理普通任务和定时任务
         *   构造方法参数：创建的线程数，不传或传0时会创建cpu核心数 * 2的线程数，也就是cpu核心数 * 2个EventLoop
         */
        EventLoopGroup group = new NioEventLoopGroup();

        /**
         * 2.获取下一个EventLoop对象(轮询方式)
         */
        EventLoop eventLoop = group.next();

        /**
         * 3.执行普通任务(线程池的方法)
         */
        eventLoop.submit(() -> {
           log.info("eventLoop正在执行任务...");
        });

        /**
         * 4.执行定时任务(ScheduleExecutorService的方法)
         * scheduleAtFixedRate(task, initialDelay, period, TimeUnit)
         * 上面代码表示在经过initialDelay时间单位后，每period个时间单位执行一次任务task
         */
        group.next().scheduleAtFixedRate(() -> {
            log.info("eventLoop正在执行定时任务");
        }, 2, 1, TimeUnit.SECONDS);

        //5.执行io任务，上一章已经介绍了
        //关闭
        //eventLoop.shutdownGracefully();
    }
}
